import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Card, Button, Space, Slider, InputNumber, Row, Col, Typography, Upload, message } from 'antd';
import { DatabaseOutlined, ThunderboltOutlined, UploadOutlined, ReloadOutlined } from '@ant-design/icons';

const { Text, Title } = Typography;
const { Dragger } = Upload;

/**
 * 数据沙盒组件
 * 提供虚拟数据生成和自定义数据导入功能
 */
const DataSandbox = ({ onGenerateData, onImportData, onResetData }) => {
  const [nodeCount, setNodeCount] = useState(20);
  const [connectionDensity, setConnectionDensity] = useState(0.3);
  const [clusterCount, setClusterCount] = useState(3);
  const [isGenerating, setIsGenerating] = useState(false);
  const [isImporting, setIsImporting] = useState(false);

  // 生成虚拟数据
  const handleGenerateData = () => {
    setIsGenerating(true);
    
    try {
      // 生成节点
      const nodes = Array.from({ length: nodeCount }, (_, i) => ({
        id: `virtual_node_${i}`,
        label: `节点 ${i + 1}`,
        type: `cluster_${Math.floor(i / (nodeCount / clusterCount))}`,
        x: Math.random() * 800 - 400,
        y: Math.random() * 600 - 300
      }));
      
      // 生成边
      const edges = [];
      const maxEdges = Math.floor(nodeCount * (nodeCount - 1) * connectionDensity / 2);
      
      for (let i = 0; i < maxEdges; i++) {
        const source = nodes[Math.floor(Math.random() * nodeCount)];
        const target = nodes[Math.floor(Math.random() * nodeCount)];
        
        if (source.id !== target.id && !edges.some(e => 
          (e.source === source.id && e.target === target.id) ||
          (e.source === target.id && e.target === source.id)
        )) {
          edges.push({
            id: `virtual_edge_${i}`,
            source: source.id,
            target: target.id,
            label: `关系 ${i + 1}`
          });
        }
      }
      
      onGenerateData(nodes, edges);
      message.success(`已生成 ${nodes.length} 个节点，${edges.length} 条关系的虚拟数据`);
    } catch (error) {
      console.error('生成虚拟数据出错:', error);
      message.error('生成虚拟数据失败');
    } finally {
      setIsGenerating(false);
    }
  };

  // 处理文件上传
  const handleFileUpload = (info) => {
    const { status, originFileObj } = info.file;
    
    if (status === 'uploading') {
      setIsImporting(true);
      return;
    }
    
    if (status === 'done') {
      setIsImporting(false);
      
      // 读取文件内容
      const reader = new FileReader();
      reader.readAsText(originFileObj);
      reader.onload = (e) => {
        try {
          const content = e.target.result;
          let data;
          
          // 根据文件类型解析数据
          if (originFileObj.name.endsWith('.json')) {
            data = JSON.parse(content);
          } else if (originFileObj.name.endsWith('.csv')) {
            // 简单的CSV解析
            data = parseCSV(content);
          } else {
            message.error('不支持的文件格式，请上传JSON或CSV文件');
            return;
          }
          
          // 验证数据格式
          if (!data.nodes || !Array.isArray(data.nodes)) {
            message.error('数据格式错误，缺少节点数组');
            return;
          }
          
          onImportData(data.nodes, data.edges || []);
          message.success(`已导入 ${data.nodes.length} 个节点，${(data.edges || []).length} 条关系的自定义数据`);
        } catch (error) {
          console.error('解析文件出错:', error);
          message.error('解析文件失败，请检查文件格式');
        }
      };
    }
    
    if (status === 'error') {
      setIsImporting(false);
      message.error('文件上传失败');
    }
  };

  // 简单的CSV解析函数
  const parseCSV = (content) => {
    const lines = content.split('\n');
    const headers = lines[0].split(',');
    
    // 检查必要的列
    const nodeIdIndex = headers.findIndex(h => h.trim().toLowerCase() === 'id' || h.trim().toLowerCase() === 'nodeid');
    const sourceLabelIndex = headers.findIndex(h => h.trim().toLowerCase() === 'source');
    const targetLabelIndex = headers.findIndex(h => h.trim().toLowerCase() === 'target');
    
    if (nodeIdIndex === -1) {
      throw new Error('CSV文件缺少节点ID列');
    }
    
    const nodes = [];
    const edges = [];
    const nodeMap = new Map();
    
    // 解析数据行
    for (let i = 1; i < lines.length; i++) {
      if (!lines[i].trim()) continue;
      
      const values = lines[i].split(',');
      
      // 如果有source和target列，则为边数据
      if (sourceLabelIndex !== -1 && targetLabelIndex !== -1 && values[sourceLabelIndex] && values[targetLabelIndex]) {
        edges.push({
          id: `edge_${i}`,
          source: values[sourceLabelIndex].trim(),
          target: values[targetLabelIndex].trim(),
          label: `关系 ${edges.length + 1}`
        });
      } 
      // 否则为节点数据
      else if (values[nodeIdIndex]) {
        const nodeId = values[nodeIdIndex].trim();
        if (!nodeMap.has(nodeId)) {
          const node = {
            id: nodeId,
            label: nodeId,
            x: Math.random() * 800 - 400,
            y: Math.random() * 600 - 300
          };
          nodes.push(node);
          nodeMap.set(nodeId, node);
        }
      }
    }
    
    return { nodes, edges };
  };

  return (
    <Card 
      title={
        <Space>
          <DatabaseOutlined />
          <span>数据沙盒</span>
        </Space>
      }
      size="small"
    >
      <Space direction="vertical" style={{ width: '100%' }}>
        {/* 虚拟数据生成 */}
        <Card size="small" title="生成虚拟数据" bordered={false}>
          <Row gutter={[16, 16]}>
            <Col span={24}>
              <Space direction="vertical" style={{ width: '100%' }}>
                <div>
                  <Text>节点数量: {nodeCount}</Text>
                  <Slider
                    min={5}
                    max={100}
                    value={nodeCount}
                    onChange={setNodeCount}
                    marks={{ 5: '5', 50: '50', 100: '100' }}
                  />
                </div>
                
                <div>
                  <Text>连接密度: {connectionDensity.toFixed(1)}</Text>
                  <Slider
                    min={0.1}
                    max={0.8}
                    step={0.1}
                    value={connectionDensity}
                    onChange={setConnectionDensity}
                    marks={{ 0.1: '稀疏', 0.4: '中等', 0.8: '密集' }}
                  />
                </div>
                
                <div>
                  <Text>聚类数量: {clusterCount}</Text>
                  <Slider
                    min={1}
                    max={10}
                    value={clusterCount}
                    onChange={setClusterCount}
                    marks={{ 1: '1', 5: '5', 10: '10' }}
                  />
                </div>
              </Space>
            </Col>
            
            <Col span={24}>
              <Button 
                type="primary" 
                icon={<ThunderboltOutlined />} 
                onClick={handleGenerateData}
                loading={isGenerating}
                block
              >
                生成虚拟数据
              </Button>
            </Col>
          </Row>
        </Card>
        
        {/* 自定义数据导入 */}
        <Card size="small" title="导入自定义数据" bordered={false}>
          <Dragger
            name="file"
            multiple={false}
            accept=".json,.csv"
            showUploadList={false}
            customRequest={({ file, onSuccess }) => {
              setTimeout(() => {
                onSuccess("ok", file);
              }, 0);
            }}
            onChange={handleFileUpload}
          >
            <p className="ant-upload-drag-icon">
              <UploadOutlined />
            </p>
            <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
            <p className="ant-upload-hint">
              支持 JSON 或 CSV 格式，需包含节点ID和关系数据
            </p>
          </Dragger>
        </Card>
        
        {/* 重置数据 */}
        <Button 
          icon={<ReloadOutlined />} 
          onClick={onResetData}
          block
        >
          恢复原始数据
        </Button>
      </Space>
    </Card>
  );
};

DataSandbox.propTypes = {
  onGenerateData: PropTypes.func.isRequired,
  onImportData: PropTypes.func.isRequired,
  onResetData: PropTypes.func.isRequired
};

export default DataSandbox;